package org.pupil.invoke.jdk;

import org.pupil.invoke.Invocation;
import org.pupil.invoke.Invoker;
import org.pupil.invoke.MethodInvocation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: jdk反射调用方式，将方法在服务本地通过反射代理调用
 * @Author: pupil
 * @Date: 2024/07/09 下午 6:21
 */
public class JdkReflectionInvoker implements Invoker {

    // 根据方法的hashCode，绑定方法代理调用方法
    private Map<Integer, MethodInvocation> methodMap = new HashMap<>();

    @Override
    public Object invoke(Invocation invocation) throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InstantiationException {
        // 获取方法的hashCode
        final Integer methodCode = invocation.getMethodCode();
        // 当集合中找不到对应的，则方法并未被调用过，需要创建并绑定
        if (!methodMap.containsKey(methodCode)){
            // 根据类名获取类
           final Class<?> aClass = Class.forName(invocation.getClassName());
           // 根据方法名和参数类型获取方法
           final Method method = aClass.getMethod(invocation.getMethodName(),invocation.getParameterTypes());
           methodMap.put(methodCode,new MethodInvocation(aClass.newInstance(),method));
        }
        final MethodInvocation methodInvocation = methodMap.get(methodCode);
        return methodInvocation.invoke(invocation.getParameter());
    }
}
